package com.yh.csx.etl.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.FileCopyUtils;

import com.yh.csx.etl.util.ConstantUtils;
import com.yh.csx.etl.util.YamlUtils;

/**
 * etl配置管理器
 * 
 * @author Robin.Wang
 * @date 2020-03-20
 *
 */
public class EtlDataMappingManager {
    private static final Logger log = LoggerFactory.getLogger(EtlDataMappingManager.class);

    public final static SortedMap<String, EtlDataMapping> MAPPINGS = new TreeMap<String, EtlDataMapping>(); // key文件名

    /**
     * 加载配置
     * 
     * @param name 文件名
     * 
     */
    public static void loadConfigs(String name) {
        loadReourcesConfigs();
        loadExternlConfigs(name);
    }

    public static String loadConfig(String name) {
        // 先取本地文件，再取类路径
        // File filePath = new File(".." + File.separator + Constant.CONF_DIR +
        // File.separator + name);
        File filePath = new File(ConstantUtils.CONF_DIR + File.separator + name);
        if (!filePath.exists()) {
            URL url = EtlDataMappingManager.class.getClassLoader().getResource("");
            if (url != null) {
                filePath = new File(url.getPath() + name);
            }
        }
        if (filePath.exists()) {
            String fileName = filePath.getName();
            if (!fileName.endsWith(".yml")) {
                return null;
            }
            try (InputStream in = new FileInputStream(filePath)) {
                byte[] bytes = new byte[in.available()];
                in.read(bytes);
                return new String(bytes, StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new RuntimeException("Read mapping config: " + filePath.getAbsolutePath() + " error. ", e);
            }
        }
        return null;
    }

    /**
     * 加载resource 目录下的配置列表
     */
    public static void loadReourcesConfigs() {
        log.debug("加载配置文件");
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            Resource[] resources = resolver.getResources("classpath:etl/*.yml");
            for (Resource resource : resources) {
                byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
                // String configContent = Base64Utils.encodeToString(bytes);
                String configContent = new String(bytes, StandardCharsets.UTF_8);
                String fileName = resource.getFilename();
                EtlDataMapping config = YamlUtils.load(configContent, EtlDataMapping.class);
                if (config != null) {
                    MAPPINGS.put(config.getDbMapping().getRelationLayer() + "_" + fileName, config);
                }
            }

        } catch (IOException e) {
            log.error("error when load mapping configs :{}", e);
        }
    }

    /**
     * 加载本地外置配置文件
     */
    public static void loadExternlConfigs(String confDir) {
        String confPath = StringUtils.isBlank(confDir) ? ConstantUtils.CONF_DIR : confDir;
        File configDir = new File(confPath);
        if (!configDir.exists()) {
            URL url = EtlDataMappingManager.class.getClassLoader().getResource("");
            if (url != null) {
                configDir = new File(url.getPath() + confPath + File.separator);
            }
        }

        File[] files = configDir.listFiles();
        if (files != null) {
            for (File file : files) {
                log.debug("处理配置文件:{}", confPath);
                String fileName = file.getName();
                if (!fileName.endsWith(".yml")) {
                    continue;
                }
                try (InputStream in = new FileInputStream(file)) {
                    byte[] bytes = new byte[in.available()];
                    in.read(bytes);
                    String configContent = new String(bytes, StandardCharsets.UTF_8);
                    EtlDataMapping config = YamlUtils.load(configContent, EtlDataMapping.class);
                    if (config != null) {
                        MAPPINGS.put(config.getDbMapping().getRelationLayer() + "_" + fileName, config);
                    }
                } catch (IOException e) {
                    throw new RuntimeException("Read " + confPath + "mapping config: " + fileName + " error. ", e);
                }
            }
        }
    }
}
